#include "cli.h"
#include "os_mem.h"
#include "os_dev.h"
#include "sh_mem.h"
#include "semaphores.h"
#include "string.h"


extern cli_cmd_info_t *cli_info_p;

/*
* Called in OS context to initialize
* CLI framework from UART interrupt-handler's
* perspective
*/
err_t cli_init(void)
{
    dev_handle_t *dev_handle;
    err_t err_code;
    uint16_t size = sizeof(cli_cmd_info_t);
    uint8_t *name = (uint8_t *)CLI_SHARED_MEM;
    shm_open_mode_t open_mode = SHM_CREATE_ALWAYS;

    dev_handle = (dev_handle_t *)calloc(1, sizeof(dev_handle_t));
    if (!dev_handle) { return ERR_NO_MEM; }

    dev_handle->dev_info.name = calloc(1, strlen(name)+1);
    if (!dev_handle->dev_info.name) {
        free(dev_handle);
	return ERR_NO_MEM;
    }

    strcpy((uint8_t *)dev_handle->dev_info.name, name);
    dev_handle->dev_info.type = DEVICE_TYPE_SHMEM;
    dev_handle->dev_info.size  = size;
    dev_handle->open_mode = open_mode;
    dev_handle->access_info.permissions = DEVICE_MODE_WRITE;

    open_device((uint32_t)dev_handle);
  
    err_code = dev_handle->err_code;
    if (dev_handle->err_code == ERR_SUCCESS) {
	cli_info_p = (cli_cmd_info_t *)dev_handle->dev_info.address;
	err_code = sem_create2(&cli_info_p->cli_sem, true, true);
	if (err_code != ERR_SUCCESS) {
	    close_device((uint32_t)dev_handle);
	} else {
	    cli_info_p->client_busy = false;
	    strcpy(cli_info_p->prompt, (uint8_t *)"#");
	}
    } 
    
    if (err_code != ERR_SUCCESS) {
        free((void *)dev_handle->dev_info.name);
	free((void *)dev_handle);
    }

    return err_code;
}
